home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 019 / lockmon / lockmon.c next >
C/C++ Source or Header  |  1995-03-17  |  7KB  |  189 lines

  1. /*
  2.  * LockMon:     determine the number of locks associated with a filesystem
  3.  *              task. I haven't figured out how to do this directly, so I
  4.  *              cheat -- if a volume is offlined, then a linked list of locks
  5.  *              is transferred to the volume's DeviceList entry. Note that
  6.  *              this isn't a permanent solution -- it won't work with hard
  7.  *              disks or RAM:, for instance.
  8.  *
  9.  * Warnings:    Uses Aztec C library internal DOSBase, which holds the
  10.  *              DOS library base pointer. Lattice does the same.
  11.  *              And ... this implementation is guesswork. Caveat emptor!
  12.  *
  13.  * Request:     Anybody know a better way?
  14.  *
  15.  * Perpetrator: Dewi Williams ..!ihnp4!druca!dewi.
  16.  *              Extremely public domain.
  17.  * 
  18.  * Version:     1.0
  19.  */
  20.  
  21. #include        <stdio.h>
  22. #include        <libraries/dos.h>
  23. #include        <libraries/dosextens.h>
  24. #include        <exec/memory.h>
  25.  
  26. /* Defines */
  27.  
  28. /* Change typeless BCPL BPTR to typed C (for struct pointers). Don't
  29.  * use this define on an APTR, that's only a badly disguised void *.
  30.  */
  31. #define BPTR_TO_C(strtag, var)  ((struct strtag *)(BADDR( (ULONG) var)))
  32.  
  33. /* And do the reverse */
  34. #define C_TO_BPTR(var)          (((ULONG)var)>>2)
  35.  
  36. /* Externs */
  37. extern struct DosLibrary *DOSBase;      /* dos library base pointer */
  38. extern short             Enable_Abort;  /* controls ^C processing */
  39.  
  40. /* ARGSUSED */
  41.  
  42. main(argc, argv)
  43. int     argc;
  44. char    **argv;
  45. {
  46.         struct  RootNode        *rn;
  47.         struct  DosInfo         *di;
  48.         struct  DeviceList      *dl;
  49.         struct  FileLock        *myFileLock;
  50.         struct   Process        *myprocess;
  51.         char                    buf[80];
  52.         struct  FileInfoBlock   *fi;
  53.         char                    *name;
  54.         char                    *btocstr();
  55.         void                    *malloc();
  56.         void                    CountLocks();
  57.         struct  Task            *FindTask();    
  58.  
  59.         Enable_Abort = 0;       /* Disable ^C processing */
  60.  
  61.         printf("Eject any volumes you wish to profile.\n");
  62.         printf("You will be requested to re-insert them as needed.\n");
  63.         printf("When ready, press RETURN to continue or 'q' to abort.\n");
  64.         (void)gets(buf);        /* Well, q and RETURN really... */
  65.  
  66.         if (buf[0] == 'q') {    /* Last chance to change your mind! */
  67.                 printf("Aborted...\n");
  68.                 exit(0);
  69.         }
  70.  
  71.         /* Wait for things to settle down (just in case) */
  72.         (void)Delay(5 * TICKS_PER_SECOND);
  73.  
  74.         /* The FileInfoBlock with guaranteed alignment. */      
  75.         if ((fi = (struct FileInfoBlock *)malloc(sizeof(*fi) )) == NULL) {
  76.                 printf("Memory allocation failure");
  77.                 exit(1);
  78.         }
  79.  
  80.         /* Note that since lockmon itself has a lock on the current
  81.          * directory, this has to be filtered out as an artefact.
  82.          * We can get its value out of the CLI stuff. Our task control
  83.          * block is the first element of the process control block,
  84.          * hence the following casting. This code fragment courtesy of
  85.          * the kind person at C-A who answered my query about finding
  86.          * the current directory on RAM:
  87.          */
  88.         myprocess = (struct Process *)FindTask(NULL);
  89.  
  90.         myFileLock = BPTR_TO_C(FileLock, myprocess->pr_CurrentDir);
  91.  
  92.         /* Any system manipulation of AmigaDOS linked lists while we're
  93.          * traversing could quite easily crash us, and the system. So
  94.          * we righteously forbid it.
  95.          */
  96.         Forbid();               /* but is this really necessary? */
  97.  
  98.         /* Take the DOS library base pointer, deduce the DOS Root Node
  99.          * address from that. Follow this to the Info substructure, which
  100.          * gives us the start address of the DeviceList chain. Volumes are
  101.          * DeviceList entries with a type of DLT_VOLUME. Note that these are
  102.          * AmigaDOS linked lists *NOT* Exec ones, so all the stuff about List,
  103.          * Node etc. doesn't apply. One box, 2 operating systems!
  104.          */
  105.         rn = (struct RootNode *)DOSBase->dl_Root;
  106.         di = BPTR_TO_C(DosInfo, rn->rn_Info);
  107.         dl = BPTR_TO_C(DeviceList, di->di_DevInfo);
  108.         
  109.         while (dl != NULL) {
  110.                 if (dl->dl_Type == DLT_VOLUME) {
  111.                         if ((name = btocstr(dl->dl_Name)) == NULL) {
  112.                                 printf("Memory allocation failure\n");
  113.                                 break;
  114.                         }
  115.                         printf("Volume '%s': ", name);
  116.                         if (dl->dl_LockList != NULL) {
  117.                                 CountLocks(BPTR_TO_C(FileLock,dl->dl_LockList),
  118.                                            fi, myFileLock);
  119.                         } else {
  120.                                 /* Either mounted or no locks... */
  121.                                 if (dl->dl_Task == NULL) 
  122.                                         printf(": no locks\n");
  123.                                 else
  124.                                         printf(": mounted\n");
  125.                         }
  126.                         free(name);                     
  127.                 }
  128.                 dl = BPTR_TO_C(DeviceList, dl->dl_Next);
  129.         }
  130.         
  131.         Permit();               /* Multi-tasking now back on */
  132.         free(fi);
  133.         exit(0);
  134. }
  135.  
  136. /*
  137.  * Traverse the linked lists of locks, counting them and printing out their
  138.  * corresponding filesystem names. 
  139.  */
  140.  
  141. void
  142. CountLocks(list, fi, mylock)
  143. struct  FileLock        *list;          /* the linked list to run through */
  144. struct  FileInfoBlock   *fi;            /* area for Examine */
  145. struct  FileLock        *mylock;        /* this one's ours */
  146. {
  147.         register struct FileLock *lptr;
  148.         register int             count = 0;
  149.         short                    Examine();     
  150.         
  151.         for(lptr=list;lptr != NULL; lptr= BPTR_TO_C(FileLock,lptr->fl_Link)){
  152.                 if (lptr == mylock) continue;
  153.                 
  154.                 if (Examine(C_TO_BPTR(lptr), fi) == FALSE) {
  155.                         /* Clicked Cancel on system requester ? */
  156.                         printf("\n\tCannot deduce filename for lock");
  157.                 } else {
  158.                         printf("\n\t%s", fi->fib_FileName);
  159.                 }
  160.                 count++;
  161.  
  162.         }
  163.         if (count > 0)
  164.                 printf("\nTotal: %d lock(s)\n", count);
  165.         else
  166.                 printf(": no locks\n");
  167. }
  168.  
  169. /*
  170.  * Convert a BCPL string to a C string. To avoid scrogging in-memory
  171.  * stuff, it malloc's off a copy first.
  172.  */
  173.  
  174. char *
  175. btocstr(b)
  176. ULONG   b;
  177. {
  178.         register char   *p, *s;
  179.         void            *malloc();
  180.  
  181.         s = (char *)BADDR(b);   /* Shift & get length-prefixed str */
  182.  
  183.         if ((p = malloc(s[0])) != NULL) {
  184.                 (void)movmem(s +1, p, s[0]);    /* Aztec memcpy */
  185.                 p[s[0]] = '\0';
  186.         }
  187.         return p;
  188. }
  189.